<template>
  <div :class="{}">
    <el-upload
      action="#"
      list-type="picture-card"
      :http-request="httpRequest"
      :before-upload="beforeUpload"
      v-model:file-list="uploadFileList"
      :multiple="true"
      :limit="limit"
      :on-remove="remove"
      :class="{
        hide_box: uploadFileList.length === limit,
        'small-size': small
      }"
    >
      <el-icon><Plus /></el-icon>
    </el-upload>
    <span :class="{ small: small, limit: true }" v-if="showLimit"
      >限制上传{{ props.limit }}张图片</span
    >
  </div>
</template>
<script setup>
import { ElMessage } from 'element-plus';
import api from '@/api/upload';
import { ref, watch } from 'vue';

const props = defineProps({
  modelValue: {
    default: []
  },
  accept: {
    // 限制上传类型
    default: 'jpg,png,jpeg'
  },
  maxSize: {
    // 限制文件大小
    default: 5000
  },
  minSize: {
    // 限制文件大小
    default: 0
  },
  limit: {
    // 限制文件数量
    default: 1
  },
  small: {
    // 限制文件数量
    default: false
  },
  showLimit: {
    // 显示限制图片提示
    default: true
  }
});

const emit = defineEmits({
  change(value) {
    return value;
  },
  ['update:modelValue'](value) {
    return value;
  }
});

// 前端渲染展示数组
const uploadFileList = ref([]);
watch(
  () => props.modelValue,
  (val) => {
    const fileList = val.map((res, index) => {
      return {
        url: res,
        uuid: index,
        src: res
      };
    });
    uploadFileList.value = [...fileList];
  },
  {
    immediate: true
  }
);

// 自定义上传文件
async function httpRequest(data) {
  const src = await api.uploadImg({
    file: data.file
  });
  uploadFileList.value = uploadFileList.value.map((res) => {
    if (res.uid === data.file.uid) {
      return {
        ...res,
        src
      };
    } else {
      return {
        ...res
      };
    }
  });
  const fileList = uploadFileList.value.map((res) => {
    return res.src;
  });
  emit('change', fileList);
  emit('update:modelValue', fileList);
  ElMessage.success('上传图片成功');
}

function beforeUpload(file) {
  const ext = file.name.match(/\.([^.]+)$/)[1];
  if (props.accept.split(',').indexOf(ext) === -1) {
    ElMessage.error(`只能上传 ${props.accept} 类型的文件`);
    return false;
  }
  if (uploadFileList.value.length >= props.limit) {
    ElMessage.error(
      `图片已达最大上传数量 (仅可上传${props.limit}张)`
    );
    return false;
  }
  if (props.minSize && file.size / 1024 < props.minSize) {
    ElMessage.error(
      `上传图片大小不能小于 ${props.minSize}KB!`
    );
    return false;
  }
  if (props.maxSize && file.size / 1024 > props.maxSize) {
    ElMessage.error(
      `上传图片大小不能超过 ${props.maxSize}KB!`
    );
    return false;
  }
}

function remove() {
  const fileList = uploadFileList.value.map((res) => {
    return res.src;
  });
  emit('change', fileList);
  emit('update:modelValue', fileList);
}
</script>

<style lang="scss" scoped>
::v-deep {
  .hide_box .el-upload--picture-card {
    display: none !important;
  }
  .small-size {
    .el-upload-list--picture-card .el-upload-list__item {
      width: 90px;
      height: 90px;
    }

    .el-upload {
      width: 90px;
      height: 90px;
    }
  }
}

.small {
  font-size: 12px;
}

.limit{
  color: var(--el-text-color-regular);
}
</style>
